<?php


namespace common\models\service;


use common\helpers\AdminExportApi;
use common\helpers\commonApi;
use yii\db\Expression;
use yii\helpers\Url;
use Yii;

class BaseController
{
    public string $model;

    /**
     * beforeAction发生错误时的跳转
     * @param string $msg
     * @param string $url
     * @param int $code
     * @return bool
     */
    public function bError($msg='',$url='',$code=-1){
        $msg=$msg?:"发生错误";
        if(Yii::$app->request->isGet && !Yii::$app->request->isAjax){
            if($url){
                $url=is_array($url)?$url:(array)$url;
            }else{
                $url=[Yii::$app->params['errorPath'],'msg'=>$msg];
            }
            Yii::$app->response->redirect($url);
        }else{
            $url=$url?Url::toRoute($url):'';
            Yii::$app->response->data =commonApi::message($msg,false,[],$code,$url);
        }
        return false;
    }

    /**
     * 首页
     */
    public function actionIndex()
    {
        if (Yii::$app->request->isPost) {
            // 获取参数
            $argList = func_get_args();
            $pageList = $argList[0]??true;
            $extMap = $argList[1]??[];
            $extSort = $argList[2]??[];
            $with = $argList[3]??[];
            $map = [];
            $order_column = 'id';
            $order_sort = 'asc';
            $pageNum = 1;
            $pageSize = defined('PAGE_LIMIT') ? PAGE_LIMIT : 10;
            $total = 0;

            $param = \Yii::$app->request->post();
            if ($param) {
                //表单的条件 where 的条件
                if (!empty($param['where']) && is_array($param['where'])) {
                    foreach ($param['where'] as $paramField => $paramValue) {
                        $paramValue = trim($paramValue);
                        if ($paramValue !== '') {
                            $map[] = [$paramField => $paramValue];
                        }
                    }
                }
                //表单的条件 like 的条件
                if (!empty($param['like']) && is_array($param['like'])) {
                    foreach ($param['like'] as $paramField => $paramValue) {
                        $paramValue = trim($paramValue);
                        if ($paramValue !== '') {
                            $map[] = ['like', $paramField, $paramValue];
                        }
                    }
                }
                //表单的条件 between 的条件
                if (!empty($param['between']) && is_array($param['between'])) {
                    foreach ($param['between'] as $paramField => $paramValue) {
                        if (is_array($paramValue) && count($paramValue) > 1) {
                            $start = $paramValue['start'];
                            $end = $paramValue['end'];
                            if ($start || $end) {
                                if ($start && $end) {
                                    $map[] = ['between', $paramField, $start, $end];
                                } elseif ($start) {
                                    $map[] = ['>', $paramField, $start];
                                } elseif ($end) {
                                    $map[] = ['<', $paramField, $end];
                                }
                            }
                        }
                    }
                }
                //表单的条件 findinset 的条件
                if (!empty($param['findinset']) && is_array($param['findinset'])) {
                    foreach ($param['findinset'] as $paramField => $paramValue) {
                        $paramValue = trim($paramValue);
                        if ($paramValue !== '') {
                            $map[] = [$paramField ,'findinset', $paramValue];
                        }
                    }
                }
                //排序条件
                if (!empty($param['orderByColumn'])) {
                    $order_column = trim($param['orderByColumn']);
                }
                if (!empty($param['isAsc'])) {
                    $order_sort = trim($param['isAsc']);
                }
                // 分页条件
                if (!empty($param['pageNum'])) $pageNum = intval($param['pageNum']);
                if (!empty($param['pageSize'])) $pageSize = intval($param['pageSize']);
            }

            if ($extMap) { // 查询条件合并
                $map = array_merge($map, $extMap);
            }

            $extSort = $extSort ?: [[$order_column, $order_sort]];// 指定排序

            $offset = ($pageNum - 1) * $pageSize; //分页开始

            //拼接sql
            $query = $this->model::find()->where('1');
            if ($with){
                $query->with($with);
            }
            if (!empty($map)) {
                $query = $this->bWhereFilter($query, $map);
            }
            //若开启了分页获取总数
            if ($pageList) {
                $total = $query->count();
            }
            if (!empty($select)) { //指定查询字段
                $query = $query->select($select);
            }
            $export = $param['isExport']??'0';
            if (!$export){
                if ($pageList) { //指定分页
                    $query = $query->offset($offset)->limit($pageSize);
                }
            }
            if (!empty($extSort)) { // 指定排序
                $orderBy = [];
                foreach ($extSort as $key => $val) {
                    if (is_array($val)) {
                        $orderBy[] = $val[0] . ' ' . $val[1];
                    } else {
                        $orderBy[] = $key . ' ' . $val;
                    }
                }
                $orderBy = implode(',', $orderBy);
                $query = $query->orderBy($orderBy);
            }


            //导出判断
            if($export){
                $list = $query->all();
                $exportData = $this->handelExport($list);
                return AdminExportApi::run(new $this->model(),$exportData);
            }else{
                $list = $query->asArray()->all();
            }

            if (!$pageList) {
                $total = count($list);
            }
            return commonApi::message('操作成功', true, $list, 0, '', ['total' => (int)$total]);
        } else {
            return $this->bError('不能解析');
        }
    }
    protected function handelExport($list,$columns=[],$headers=[]){
        return ['list'=>$list,'columns'=>$columns,'headers'=>$headers];
    }

    /**
     * 处理自定义数组where条件
     * @param $query
     * @param $map
     * @return mixed
     */
    public function bWhereFilter($query, $map)
    {
        if (empty($map)) return $query;
        if (is_array($map)) {
            foreach ($map as $key => $val) {
                if (is_array($val)) {
                    if (count($val) == 3) {
                        if ($val[1] === 'findinset') {
                            $val = new Expression('FIND_IN_SET("' . $val[2] . '", ' . $val[0] . ')');
                        } elseif ($val[1] === 'in') {
                            $val = [$val[0] => $val[2]];
                        } elseif ($val[1] === '=') {
                            $val = [$val[0] => $val[2]];
                        }
                    }
                    $query = $query->andWhere($val);
                } else {
                    $query = $query->andWhere([$key => $val]);
                }

            }
        } else {
            $query = $query->andWhere($map);
        }
        return $query;
    }
}